/*
 * Copyright 2013 Wajdi Hh "wajdihh@gmail.com" .
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hh.ui.widget;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.hh.droid.R;
import com.hh.listeners.OnPopupMenuItemClickListener;

/**
 * 
 * A Popup Menu dialog  to display list of items or custom adapter
 * 
 * @author WajdiHh : Last modification : 23/05/2013
 *
 */
public class UiPopupMenu extends Dialog implements OnItemClickListener{

	/**
	 * To fix popup Menu by contribution of a view
	 */
	public enum UIPopUpMenu_ALIGN{TOP,BOTTOM,RIGHT,LEFT};
	/**
	 * To specify  popup Menu type : Action : the items are clickable / Info : items not clickable
	 */
	public enum PopUpMenuTYPE{ACTION,INFO};
	private Context _mContext;
	private Point _mPt;
	private int _mWidth,_mHeight;
	private int _mDividerColor;
	private  int _mBackgroundColor;
	private Object _mSelection;
	private String _mTextSelection="";
	private int _mPositionSelection;
	private int _mMaxItems;
	private ArrayList<HashMap<String, String>> _myData;
	private Resources _mRes;
	private int _mX,_mY;
	private int lViewX,lViewY;
	private int _mTextViewColor;
	private ListView _mItemsList;
	private PopUpMenuTYPE _myPopupType;
	private long[] _myItemsIDs;
	private OnPopupMenuItemClickListener _mPopupMenuItemClickListener;
	
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 */
	public UiPopupMenu(Context context,String[] pItemsName) {
		super(context,android.R.style.Theme_Translucent);	

		initPopupDialog(context, null,pItemsName,null,null,null,null);
	}

	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 * @param pDrawablesRes[] : Drawables resources to show icon on the left of Item name
	 */
	
	public UiPopupMenu(Context context,String[] pItemsName,int[] pDrawablesRes) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,null,pItemsName,pDrawablesRes,null,null,null);

	}
	
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 * @param pIDs : ID list for each element
	 */
	public UiPopupMenu(Context context,String[] pItemsName,long [] pIDs) {
		super(context,android.R.style.Theme_Translucent);	

		initPopupDialog(context, null,pItemsName,null,pIDs,null,null);
	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 * @param pDrawablesRes[] : Drawables resources to show icon on the left of Item name
	 * @param pIDs : ID list for each element
	 */
	public UiPopupMenu(Context context,String[] pItemsName,int[] pDrawablesRes,long [] pIDs) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,null,pItemsName,pDrawablesRes,pIDs,null,null);

	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 * @param pPoint :Point object to fix X and Y coordinates of the menu on the Screen
	 */
	public UiPopupMenu(Context context,Point pPoint,String[] pItemsName) {
		super(context,android.R.style.Theme_Translucent);	

		initPopupDialog(context, pPoint,pItemsName,null,null,null,null);
	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pItemsName[]. Items names of the list.
	 * @param pDrawablesRes[] : Drawables resources to show icon on the left of item name
	 * @param pPoint :Point object to fix X and Y coordinates of the menu on the Screen
	 */
	public UiPopupMenu(Context context,Point pPoint,String[] pItemsName,int[] pDrawablesRes) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,pPoint,pItemsName,pDrawablesRes,null,null,null);
	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pPoint :Point object to fix X and Y coordinates of the menu on the Screen
	 * @param pAdapter : Adapter used to show items in the menu list
	 */
	public UiPopupMenu(Context context,Point pPoint,BaseAdapter pAdapter) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,pPoint,null,null,null,pAdapter,null);
	}
	
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pPoint :Point object to fix X and Y coordinates of the menu on the Screen
	 * @param pHeaderView : Header of items list
	 * @param pItemsName[]: Items names of the list.
	 */
	public UiPopupMenu(Context context,String[] pItemsName,View pHeaderView) {
		super(context,android.R.style.Theme_Translucent);	

		initPopupDialog(context, null,pItemsName,null,null,null,pHeaderView);
	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pPoint :Point object to fix X and Y coordinates of the menu on the Screen
	 * @param pHeaderView : Header of items list
	 * @param pItemsName[]: Items names of the list.
	 * @param pDrawablesRes[] : Drawables resources to show icon on the left of item name
	 */
	public UiPopupMenu(Context context,String[] pItemsName,int[] pDrawablesRes,View pHeaderView) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,null,pItemsName,pDrawablesRes,null,null,pHeaderView);

	}
	/**
	 * <br>
	 * Constructor
	 * 
	 * @author WajdiHh
	 * @param context The context where the View associated with this UiPopupMenu is running
	 * @param pAdapter : Adapter used to show items in the menu list
	 */
	public UiPopupMenu(Context context,BaseAdapter pAdapter) {
		super(context,android.R.style.Theme_Translucent);

		initPopupDialog(context,null,null,null,null,pAdapter,null);
	}

	
	/**
	 * <br>
	 * Specify the popup menu type
	 * 
	 * @author WajdiHh
	 * @param pType
	 */
	public void setPopupMenuType(PopUpMenuTYPE pType){
		_myPopupType=pType;
		if(pType==PopUpMenuTYPE.INFO)
			_mItemsList.setEnabled(false);
	}
	/**
	 * <br>
	 * set x position of popupMenu on the screen
	 * 
	 * @author WajdiHh
	 * @param pX : Value of X 
	 */
	public void setX(int pX){
		_mPt.x=pX;
	}
	/**
	 * <br>
	 * set y position of popupMenu on the screen
	 * 
	 * @author WajdiHh
	 * @param pY : Value of Y 
	 */
	public void setY(int pY){
		_mPt.y=pY;
	}
	/**
	 * <br>
	 * set margin top of popupMenu
	 * 
	 * @author WajdiHh
	 * @param pMargin : Value of margin 
	 */
	public void setMarginTop(int pMargin){
		_mY=_mY+pMargin;
	}
	/**
	 * <br>
	 * set margin Bottom of popupMenu
	 * 
	 * @author WajdiHh
	 * @param pMargin : Value of margin 
	 */
	public void setMarginBottom(int pMargin){
		_mY=_mY-pMargin;
	}
	/**
	 * <br>
	 * set margin Left of popupMenu
	 * 
	 * @author WajdiHh
	 * @param pMargin : Value of margin 
	 */
	public void setMarginLeft(int pMargin){
		_mX=_mX+pMargin;
	}
	/**
	 * <br>
	 * set margin right of popupMenu
	 * 
	 * @author WajdiHh
	 * @param pMargin : Value of margin 
	 */
	public void setMarginRigth(int pMargin){
		_mX=_mX-pMargin;
	}
	/**
	 * <br>
	 * set max number of the items to show
	 * 
	 * @author WajdiHh
	 * @param pMaxItems : max number of popup menu items
	 */
	public void setMaxItems(int pMaxItems){	
		_mMaxItems=pMaxItems;
		_mHeight=getItemHightofListView(_mItemsList);
	}
	/**
	 * <br>
	 * return the max of showing items
	 * 
	 * @author WajdiHh
	 * @return max of showing items
	 */
	public int getMaxItems(){
		return _mMaxItems;
	}
	/**
	 * <br>
	 * return the selection items OBJECT of the popupmenu 
	 * 
	 * @author WajdiHh
	 * @return text selection
	 */
	public Object getSelection(){
		return _mSelection;
	}
	/**
	 * <br>
	 * return the position of the selected item 
	 * 
	 * @author WajdiHh
	 * @return the selection position
	 */
	public int getSelectionPosition(){
		return _mPositionSelection;
	}
	/**
	 * <br>
	 * set selection of an item in the list 
	 * 
	 * @author WajdiHh
	 * @param pPosition :position of an Item in  the list
	 */
	public void setSelectionPosition(int pPosition){
		_mPositionSelection=pPosition;
	}
	/**
	 * <br>
	 * return the text selection
	 * 
	 * @author WajdiHh
	 * @return text selection
	 */
	public String getTextSelection(){

		if(_mItemsList.getCount()>_mPositionSelection){
			_mSelection=_mItemsList.getItemAtPosition(_mPositionSelection);
			HashMap<String, String> lItem=_myData.get(_mPositionSelection);
			_mTextSelection=lItem.get("TXT");
		}
		return _mTextSelection;
	}
	/**
	 * <br>
	 * set the color of the separator between list items
	 * 
	 * @author WajdiHh
	 * @param pColor :Color
	 */
	public void setDividerItemsColor(int pColor){
		_mDividerColor=pColor;
		_mItemsList.setDivider(new ColorDrawable(_mDividerColor));
		_mItemsList.setDividerHeight(1);
	}
	/**
	 * <br>
	 * set the background color of the popupMenu
	 * 
	 * @author WajdiHh
	 * @param pColor :Color
	 */
	public void setBackgroundColor(int pColor){
		_mBackgroundColor=pColor;
	}
	/**
	 * <br>
	 * set text color item
	 * 
	 * @author WajdiHh
	 * @param pColor :Color
	 */
	public void setTextItemColor(int pColor){
		_mTextViewColor=pColor;
	}
	/**
	 * <br>
	 * set position on the screen
	 * 
	 * @author WajdiHh
	 * @param Point :p
	 */
	public void setPositionOnScreen(Point p){
		_mPt=p;
	}
	/**
	 * <br>
	 * Get the position of String sequences on the items List
	 * 
	 * @author WajdiHh
	 * @param pText
	 * @return
	 */
	public int getPosFromText(String pText){
		
		int lPos=-1;
		for (int i = 0; i < _myData.size(); i++) {
			
			HashMap<String, String> lItem=_myData.get(i);
			String lCurrentItem=lItem.get("TXT");
			
			if(lCurrentItem.equals(pText)){
				lPos=i;
				break;
			}
		}
		return lPos;
	}
	/**
	 * <br>
	 * set popupMenu Align position relative of a view
	 * 
	 * @author WajdiHh
	 * @param Point :p
	 */
	public void setAlignView(View v,UIPopUpMenu_ALIGN pAlign){
		 
		int[] lLocation=new int[2];
		v.getLocationOnScreen(lLocation);	
		
		switch (pAlign) {
		case TOP:
			lViewY=-getHeight();
			break;
		case BOTTOM:
			lViewY=v.getHeight();
			break;
		case RIGHT:
			lViewX=v.getWidth();
			break;
		case LEFT:
			lViewX=-getWidth();
			break;
		}

		Point p=new Point(lLocation[0]+lViewX, lLocation[1]+lViewY);
		this.setPositionOnScreen(p);
	}
	/**
	 * <br>
	 * set popupMenu width <b>( Default is 200 dp )</b>
	 * 
	 * @author WajdiHh
	 * @param pWidth
	 */
	public void setWidth(int pWidth){
		_mWidth=pWidth;
	}
	/**
	 * <br>
	 * set popupMenu height <b>( Default is 50 X number of items )</b>
	 * 
	 * @author WajdiHh
	 * @param pHeight
	 */
	public void setHeight(int pHeight){
		_mHeight=pHeight;
	}
	/**
	 * <br>
	 * return popupMenu width
	 * 
	 * @author WajdiHh
	 * @return width
	 */
	public int getWidth(){
		return _mWidth;
	}
	/**
	 * <br>
	 * return popupMenu height
	 * 
	 * @author WajdiHh
	 * @return height
	 */
	public int getHeight(){
		return _mHeight;
	}
	/**
	 * <br>
	 * Register a callback to be invoked when popup menu items clicked
	 * 
	 * @author WajdiHh
	 * @param pListener : pListener: the listener to handle items click
	 * @see OnPopupMenuItemClickListener
	 */
	public void setOnPopupMenuItemClickListener(OnPopupMenuItemClickListener pListener){
		_mPopupMenuItemClickListener=pListener;
	}
	
	private void initPopupDialog(Context context,Point p,String[] pItemsName,int[] pDrawables,long[] pIDs,BaseAdapter pAdapter,View pView){	

		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.ui_popup_menu);
		_mContext=context;
		_mRes=context.getResources();
		_mDividerColor=Color.GRAY;
		_mTextViewColor=Color.BLACK;
		_mBackgroundColor=_mRes.getColor(R.color.holo_gray_lev0);
		_mPt=new Point(0, 0);
	    _myPopupType=PopUpMenuTYPE.ACTION;
	    _mPositionSelection=0;
	    
		if(p!=null)
			_mPt=p;

		if(pAdapter==null){
			_myItemsIDs=pIDs;
			setListView(context, pItemsName, pDrawables,pView);
		}
		else
			setListViewWithAdapter(pAdapter);

		this.setCanceledOnTouchOutside(true);
	}

	
	private void setListView(Context context,String[] pItemsName,int[] pDrawables,View pView){

		_myData=new ArrayList<HashMap<String,String>>();
		boolean lhasDrawable=false;
		if(pDrawables!=null)
			lhasDrawable=true;

		for (int i = 0; i < pItemsName.length; i++) {

			HashMap<String, String> lMap=new HashMap<String, String>();
			lMap.put("TXT", pItemsName[i]);
			if(lhasDrawable && pDrawables.length>i)
				lMap.put("IM", ""+pDrawables[i]);

			_myData.add(lMap);
		}
		String [] from={"TXT",""};
		int[] to={R.id.popup_Text,0};

		if(lhasDrawable){
			from[1]="IM";
			to[1]=R.id.popup_Image;
		}
		SimpleAdapter lAdapter=new SimpleAdapter(context, _myData, R.layout.rowlv_popupmenu, from, to){
			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				View v= super.getView(position, convertView, parent);
				v.setBackgroundResource(R.drawable.selector_button);
				TextView lTv=(TextView) v.findViewById(R.id.popup_Text);
				lTv.setTextColor(_mTextViewColor);
				
				return v;
			}
		};

		
		_mItemsList=(ListView) findViewById(R.id.MyList);
		
		if(pView!=null)
			_mItemsList.addHeaderView(pView);
		
		_mItemsList.setAdapter(lAdapter);
		if(_mItemsList.getCount()>_mPositionSelection){
			_mSelection=_mItemsList.getItemAtPosition(_mPositionSelection);
			HashMap<String, String> lItem=_myData.get(_mPositionSelection);
			_mTextSelection=lItem.get("TXT");
		}
		_mItemsList.setOnItemClickListener(this);

		_mItemsList.setDivider(new ColorDrawable(_mDividerColor));
		_mItemsList.setDividerHeight(1);
		_mItemsList.setVerticalFadingEdgeEnabled(false);
		
		_mHeight=getItemHightofListView(_mItemsList);
		_mWidth=(int)_mContext.getResources().getDimension(R.dimen.WidthPopUpMenu);
	}


	private void setListViewWithAdapter(BaseAdapter pAdapter){

		_mItemsList=(ListView) findViewById(R.id.MyList);
		_mItemsList.setAdapter(pAdapter);
		_mItemsList.setOnItemClickListener(this);
		_mItemsList.setDivider(new ColorDrawable(_mDividerColor));
		_mItemsList.setDividerHeight(1);
		
		if(_mItemsList.getCount()>_mPositionSelection)
			_mSelection=_mItemsList.getItemAtPosition(_mPositionSelection);
		
		_mHeight=getItemHightofListView(_mItemsList);
		_mWidth=(int)_mContext.getResources().getDimension(R.dimen.WidthPopUpMenu);
	}
	private int getItemHightofListView(ListView listView) {
		ListAdapter mAdapter = listView.getAdapter();
		
		int lNbrOfItems=mAdapter.getCount();
		if(_mMaxItems!=0)
			lNbrOfItems=_mMaxItems;
		
		return (lNbrOfItems* (int)_mContext.getResources().getDimension(R.dimen.heightPopUpItem))+10;

	}
	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();

		View view = getWindow().getDecorView();
		WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();
		lp.x = _mPt.x+_mX;
		lp.y = _mPt.y+_mY;
		lp.gravity = Gravity.LEFT | Gravity.TOP;
		lp.width = _mWidth;
		lp.height = _mHeight;
		((Activity)_mContext).getWindowManager().updateViewLayout(view, lp);
		_mItemsList.setBackgroundColor(_mBackgroundColor);
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {

		if(_myPopupType==PopUpMenuTYPE.ACTION){
			if(_myData!=null){
				_mPositionSelection=position;
				HashMap<String, String> lItem=_myData.get(_mPositionSelection);
				_mTextSelection=lItem.get("TXT");
			}

			int lId=0;
			if(_myItemsIDs!=null && _myItemsIDs.length>position)
				lId=(int) _myItemsIDs[position];
			
			if(_mPopupMenuItemClickListener!=null)
				_mPopupMenuItemClickListener.onPopupMenuItemClick(v,position,lId);
		}
		dismiss();
	}
}
